package cn.mazexal.examapi.controller;

import cn.mazexal.examapi.common.models.*;
import cn.mazexal.examapi.models.db.ExamPageDO;
import cn.mazexal.examapi.models.form.CommitExamForm;
import cn.mazexal.examapi.models.form.ReportQuestionForm;
import cn.mazexal.examapi.models.qry.ExamDetailQry;
import cn.mazexal.examapi.models.qry.ExamPageListQry;
import cn.mazexal.examapi.models.qry.IDQry;
import cn.mazexal.examapi.models.qry.MenuQuestionQry;
import cn.mazexal.examapi.models.redisKeys.RedisCommonKey;
import cn.mazexal.examapi.models.redisKeys.RedisExamKey;
import cn.mazexal.examapi.models.vo.*;
import cn.mazexal.examapi.services.ExamService;
import cn.mazexal.examapi.services.QuestionService;
import cn.mazexal.examapi.services.RedisService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author: Mazexal
 * Date: 2025/5/24
 */
@RestController
@RequestMapping("/exam")
@Tag(name = "exam", description = "考试接口")
public class ExamController extends BaseController {

    @Resource
    private ExamService examService;

    @Resource
    private QuestionService questionService;

    @Resource
    private RedisService redisService;

    @PostMapping("/getQuestionByMenuId")
    @Tag(name = "getQuestionByMenuId", description = "通过菜单ID获取题目")
    public SingleResponse<ExamQuestionWithMaterialsVO> getQuestionByMenuId(@RequestBody MenuQuestionQry qry) {
        Long userId = getUserId();
        String key = RedisExamKey.getExamByMenuIdKey(qry.getMenuId(), userId);
        if (redisService.tryLock(key, RedisCommonKey.keyValue, 5, TimeUnit.SECONDS)) {
            ExamQuestionWithMaterialsVO res = questionService.getExamQuestionListByMenuIds(qry.getMenuId(),
                    qry.getExamBankId(), qry.getPageSize(),
                    userId, qry.getQuestionType());
            List<Long> materialsIds =
                    res.getQuestionList().stream().map(ExamQuestionVO::getMaterialsId).filter(x -> x > 0).toList();
            List<ExamQuestionMaterialsVO> materialsList =
                    questionService.getExamQuestionMaterialsList(materialsIds);
            res.setMaterialsList(materialsList);
            redisService.releaseLock(key, RedisCommonKey.keyValue);
            return SingleResponse.of(res);
        }
        return SingleResponse.error(new CustomerError("500", "请勿重复提交"));
    }

    @PostMapping("/commitExam")
    @Tag(name = "commitExam", description = "提交考试, 这里是提交")
    public SingleResponse<ExamResultVO> commitExam(@RequestBody CommitExamForm form) {
        Long userId = getUserId();
        String key = RedisExamKey.getUserCommitExamKey(form.getUserExamId(), userId);
        if (redisService.tryLock(key, RedisCommonKey.keyValue, 5, TimeUnit.SECONDS)) {
            ExamResultVO resVO = examService.commitExam(form);
            redisService.releaseLock(key, RedisCommonKey.keyValue);
            return SingleResponse.of(resVO);
        } else {
            return SingleResponse.error(new CustomerError("500", "请勿重复提交"));
        }
    }


    @PostMapping("/getRealExamList")
    @Tag(name = "getRealExamList", description = "获取真题列表")
    public PagedResponse<ExamPageVO> getRealExamList(@RequestBody ExamPageListQry qry) {
        PagedData<ExamPageVO> res = examService.getRealExamList(qry);
        return PagedResponse.of(res);
    }


    @PostMapping("/getRealExamDetail")
    @Tag(name = "getRealExamDetail", description = "获取真题详情")
    public SingleResponse<ExamPageVO> getRealExamDetail(@RequestBody ExamDetailQry qry) {
        qry.setUserId(getUserId());
        return SingleResponse.of(examService.getRealExamDetail(qry));
    }

    @PostMapping("/getRealExamDetailAndJoinExam")
    @Tag(name = "getRealExamDetailAndJoinExam", description = "获取真题详情并加入考试")
    public SingleResponse<ExamPageVO> getRealExamDetailAndJoinExam(@RequestBody ExamDetailQry qry) {
        qry.setUserId(getUserId());
        ExamPageVO realExamDetail = examService.getRealExamDetail(qry);
        Long userExamLog = questionService.addUserExamLog(qry.getExamBankId(), qry.getId(), getUserId(),
                realExamDetail.getExamType());
        realExamDetail.setUserExamLogId(userExamLog);
        return SingleResponse.of(realExamDetail);
    }

    @PostMapping("/reportQuestion")
    @Tag(name = "reportQuestion", description = "题目报错")
    public SingleResponse<Boolean> reportQuestion(ReportQuestionForm form) {
        if (StringUtils.isBlank(form.getContext())) {
            return SingleResponse.error(new CustomerError("500", "请填写问题内容"));
        }
        if (form.getContext().length() > 500) {
            return SingleResponse.error(new CustomerError("500", "问题描述过长, 限定500字以内"));
        }
        Long userId = getUserId();
        form.setUserId(userId);
        boolean res = questionService.reportQuestion(form);
        return SingleResponse.of(res);
    }
}
